#define _DEFAULT_SOURCE
#include <mqueue.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>

#define MSG_LEN 32

void signal_handler(int sig)
{
    printf("清理消息队列\n");
    mq_unlink("/test_mq");
    exit(EXIT_SUCCESS);
}

int main(int argc, char const *argv[])
{
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
    pid_t subprocess = fork();

    if (subprocess < 0)
    {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (subprocess == 0)
    {
        // 子进程
        // 消息队列的使用
        // 打开
        struct mq_attr attr;
        attr.mq_maxmsg = 10;
        attr.mq_msgsize = MSG_LEN;
        mqd_t mq = mq_open("/test_mq", O_CREAT | O_RDWR, 0644, &attr);

        if (mq < 0)
        {
            perror("mq_open");
            exit(EXIT_FAILURE);
        }

        // 接收
        char buf[MSG_LEN];
        while (1)
        {

            int result = mq_receive(mq, buf, MSG_LEN, 0);
            if (result < 0)
            {
                perror("mq_receive");
            }
            printf("接收到消息: %s\n", buf);
        }
    }
    else
    {
        // 父进程
        struct mq_attr attr;
        attr.mq_maxmsg = 10;
        attr.mq_msgsize = MSG_LEN;
        mqd_t mq = mq_open("/test_mq", O_CREAT | O_RDWR, 0644, &attr);

        if (mq < 0)
        {
            perror("mq_open");
            exit(EXIT_FAILURE);
        }

        // 向队列中发送消息
        int count = 0;
        char buf[MSG_LEN];
        while (1)
        {
            count++;
            snprintf(buf, MSG_LEN, "hello world %d!", count);
            int result = mq_send(mq, buf, MSG_LEN, 0);
            if (result < 0)
            {
                perror("mq_send");
            }
            sleep(1);
        }
    }

    return 0;
}
